home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / ANMFORMT.ZIP / SHOWANIM.C < prev    next >
Text File  |  1991-08-23  |  8KB  |  325 lines

  1. /* 
  2.     This is a small program to play a deluxe animate file.  No attempt has
  3.     been made to time the animation speed correctly.  The playback speed will
  4.     be dictated by the speed of your machine.
  5. */
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <malloc.h>
  10.  
  11. #define EXIT_FAILURE 1
  12. #define EXIT_SUCCESS 0
  13.  
  14. #define    TRUE    1
  15. #define    FALSE    0
  16.  
  17. /* Typedefs for portability. */
  18.  
  19. typedef char                 BOOL;        /* 0==FALSE, 1==TRUE */
  20. typedef char                 BYTE;        /* signed    8-bit number */
  21. typedef unsigned char     UBYTE;    /* unsigned  8-bit number */
  22. typedef int                 WORD;        /* signed   16-bit number */
  23. typedef unsigned int     UWORD;    /* unsigned 16-bit number */
  24. typedef long                 LONG;        /* signed   32-bit number */
  25. typedef unsigned long     ULONG;    /* unsigned 32-bit number */
  26.  
  27. /* function prototypes */
  28. void SetVideoMode(UWORD mode);
  29. WORD    GetVideoMode(void);
  30. void LoadPalette(UWORD numcolors, UWORD startcolor, UBYTE *paletteaddr);
  31. void InitMouse(void);
  32. void ShowMouse(void);
  33. void HideMouse(void);
  34. void ReadMouse(UWORD *buttonstate, UWORD *mousex, UWORD *mousey);
  35. void PlayRunSkipDump(UBYTE *srcbuf, UBYTE *dstbuf);
  36. void cls(UWORD color);
  37.  
  38. #include "showanim.h"        /* contains structures for large page files */
  39.  
  40. lpfileheader lpheader;        /* file header will be loaded into this structure */
  41.  
  42. lp_descriptor LpArray[256]; /* arrays of large page structs used to find frames */
  43.  
  44. UBYTE lppalette[768];        /* anim file palette is loaded here */
  45. UBYTE *screen = (char *)0xA0000000l;    /* pointer to the screen */
  46.  
  47. UWORD curlpnum=0xFFFF;        /* initialize to an invalid Large page number */
  48.  
  49. lp_descriptor curlp;            /* header of large page currently in memory */
  50.  
  51. UWORD *thepage;                /* pointer to the buffer where current large page is loaded */
  52.  
  53. FILE    *infile;                    /* input file pointer */
  54.  
  55. ULONG    inputsize;                /* input file size.  I allways get this out of habbit */
  56.  
  57.  
  58. /* support routines for the rest of the program start here */
  59.  
  60. /* given a frame number return the large page number it resides in */
  61. UWORD findpage(framenumber)
  62. UWORD framenumber;
  63. {
  64.     UWORD i;
  65.  
  66.     for(i=0; i<lpheader.nLps; i++)
  67.     {
  68.         if(LpArray[i].baseRecord <= framenumber && LpArray[i].baseRecord + LpArray[i].nRecords > framenumber)
  69.             return(i);
  70.     }
  71.     return(i);
  72. }
  73.  
  74. /* seek out and load in the large page specified */
  75. loadpage(pagenumber, pagepointer)
  76. UWORD pagenumber;
  77. UWORD *pagepointer;
  78. {
  79.     if(curlpnum!=pagenumber)
  80.     {
  81.         curlpnum=pagenumber;
  82.         fseek(infile, 0x0B00l+(LONG)pagenumber * 0x10000l,SEEK_SET);
  83.         fread(&curlp, sizeof(lp_descriptor), 1, infile);
  84.         getw(infile);    /* skip empty word */
  85.         fread(pagepointer, curlp.nBytes+(curlp.nRecords*2), 1, infile);
  86.     }
  87. }
  88.  
  89. /* This version of the decompressor is here for portability to non PC's */
  90. void CPlayRunSkipDump(srcP,dstP)
  91. BYTE *srcP;          /* srcP points at first sequence in Body */
  92. BYTE *dstP;          /* dstP points at pixel #0 on screen.     */
  93. {
  94.     BYTE cnt;
  95.     UWORD wordCnt;
  96.     UBYTE pixel;
  97.  
  98.  
  99. nextOp:
  100.         cnt = (signed char) *srcP++;
  101.         if (cnt > 0)
  102.             goto dump;
  103.         if (cnt == 0)
  104.             goto run;
  105.         cnt -= 0x80;
  106.         if (cnt == 0)
  107.             goto longOp;
  108. /* shortSkip */
  109.         dstP += cnt;            /* adding 7-bit count to 32-bit pointer */
  110.         goto nextOp;
  111. dump:
  112.         do
  113.         {
  114.             *dstP++ = *srcP++;
  115.         } while (--cnt);
  116.  
  117.         dstP += cnt;
  118.         srcP += cnt;
  119.         goto nextOp;
  120. run:
  121.         wordCnt = (UBYTE)*srcP++;        /* 8-bit unsigned count */
  122.         pixel = *srcP++;
  123.         do
  124.         {
  125.             *dstP++ = pixel;
  126.         } while (--wordCnt);
  127.  
  128.         dstP += wordCnt;
  129.         goto nextOp;
  130. longOp:
  131.         wordCnt = *((UWORD far *)srcP)++;
  132.         if ((WORD)wordCnt <= 0)
  133.             goto notLongSkip;    /* Do SIGNED test. */
  134.  
  135. /* longSkip. */
  136.         dstP += wordCnt;
  137.         goto nextOp;
  138.  
  139. notLongSkip:
  140.         if (wordCnt == 0)
  141.             goto stop;
  142.         wordCnt -= 0x8000;        /* Remove sign bit. */
  143.         if (wordCnt >= 0x4000)
  144.             goto longRun;
  145.  
  146. /* longDump. */
  147.         do 
  148.         {  
  149.             *dstP++ = *srcP++;  
  150.         } while (--wordCnt);
  151.  
  152.         dstP += wordCnt;
  153.         srcP += wordCnt;
  154.         goto nextOp;
  155.  
  156. longRun:
  157.         wordCnt -= 0x4000;        /* Clear "longRun" bit. */
  158.         pixel = *srcP++;
  159.         do 
  160.         {  
  161.             *dstP++ = pixel; 
  162.         } while (--wordCnt);
  163.  
  164.         dstP += wordCnt;
  165.         goto nextOp;
  166.  
  167. stop:    /* all done */
  168.     ;
  169. }
  170.  
  171.  
  172.  
  173. /* draw the frame sepcified from the large page in the buffer pointed to */
  174. renderframe(framenumber, pagepointer)
  175. UWORD framenumber;
  176. UWORD *pagepointer;
  177. {
  178.     UWORD offset=0;
  179.     UWORD i;
  180.     UWORD destframe;
  181.     UBYTE *ppointer;
  182.  
  183.     destframe = framenumber - curlp.baseRecord;
  184.     
  185.     for(i = 0; i < destframe; i++)
  186.     {
  187.         offset += pagepointer[i];
  188.     }
  189.     ppointer = (UBYTE *)pagepointer;
  190.  
  191.     ppointer+=curlp.nRecords*2+offset;
  192.     
  193.     if(ppointer[1])
  194.     {
  195.         ppointer += (4 + (((UWORD *)ppointer)[1] + (((UWORD *)ppointer)[1] & 1)));
  196.     }
  197.     else
  198.     {
  199.         ppointer+=4;
  200.     }
  201.      
  202. /*
  203.     this is the C version of the decompressor, uncomment it if you are not
  204.     running on a PC
  205. */
  206. /*    CPlayRunSkipDump(ppointer, screen); */
  207.  
  208.     PlayRunSkipDump(ppointer, screen);
  209. }
  210.  
  211. /* high level frame draw routine */
  212. void drawframe(framenumber)
  213. UWORD framenumber;
  214. {
  215.     loadpage(findpage(framenumber), thepage);
  216.     renderframe(framenumber, thepage);
  217. }
  218.  
  219. /* main program code */
  220. main(argc,argv)
  221. int argc;
  222. char *argv[];
  223. {
  224.     UWORD i;
  225.     UWORD framecount;
  226.     WORD    oldvideomode;
  227.     UWORD    mousebutton=0, mousex=0, mousey=0;
  228.  
  229. /* had to use "halloc" because I had to allocate a buffer exactly 64k long */
  230.     thepage =(UWORD *)halloc(0x10000l,1); /* allocate page buffer */
  231.  
  232.     if(argc < 2)
  233.     {
  234.         printf("'Showanim file.ANM' display Deluxe animate file on VGA screen.\n\n");
  235.         return EXIT_FAILURE;
  236.     }
  237.         
  238.     if((infile = fopen(argv[1],"rb")) == NULL)
  239.     {
  240.         printf("Input file not found!\n");
  241.         return EXIT_FAILURE;
  242.     }
  243.  
  244.     /* get the size of the anim file */    
  245.     fseek(infile, 0L, SEEK_END);
  246.     inputsize = ftell(infile);
  247.     rewind(infile);
  248.  
  249.     /* read the anim file header */
  250.     if(fread(&lpheader,sizeof(lpfileheader),1,infile) == NULL)
  251.     {
  252.         printf("Error reading file header!\n");
  253.         return EXIT_FAILURE;
  254.     }
  255.  
  256.     fseek(infile, 128L, SEEK_CUR);    /* skip color cycling structures */
  257.     
  258.     /* read in the color palette */
  259.     for(i=0; i<768; i+=3)
  260.     {
  261.         lppalette[i+2] = (UBYTE)((getc(infile) >> 2) & 63);        /* read red */
  262.         lppalette[i+1] = (UBYTE)((getc(infile) >> 2) & 63);        /* read green */
  263.         lppalette[i]   = (UBYTE)((getc(infile) >> 2) & 63);        /* read blue */
  264.  
  265.         getc(infile);                                /* skip over the extra pad byte */
  266.     }
  267.  
  268.     /* read in large page descriptors */
  269.     fread(LpArray,sizeof(lp_descriptor),256,infile);
  270.  
  271.     /* the file pointer now points to the first large page structure */
  272.  
  273.     oldvideomode = GetVideoMode();    /* save the current video mode */
  274.  
  275.     SetVideoMode(0x13);                /* set the video mode to 13h MCGA 256 color */
  276.  
  277.     cls(0);                                /* clear the screen to black */
  278.  
  279.     LoadPalette(256,0,lppalette);    /* init the color palette */
  280.  
  281.     InitMouse();
  282.  
  283.     HideMouse();
  284.  
  285.     drawframe(0);                    /* draw the first frame of the file */
  286.  
  287.     ShowMouse();
  288.  
  289.     mousebutton=0;
  290. /*
  291.     Remember, the last frame in the file is a delta back to the first frame.
  292.     You should only draw the first frame once and then use the last frame to 
  293.     redraw the first frame.
  294. */
  295.     while(!(mousebutton&1))
  296.     {
  297.  
  298.         for(framecount = 1; framecount <    (UWORD)lpheader.nRecords; framecount++)
  299.         {
  300.             ReadMouse(&mousebutton, &mousex, &mousey);
  301.  
  302.             while(!(mousebutton&3))
  303.                 ReadMouse(&mousebutton, &mousex, &mousey);
  304.  
  305.             if(mousebutton&1)
  306.                 break;
  307.             
  308.             HideMouse();
  309.             drawframe(framecount);
  310.             ShowMouse();
  311.         }
  312.     }
  313.  
  314.     HideMouse();
  315.     SetVideoMode(oldvideomode);
  316.     fclose(infile);
  317.  
  318.     hfree(thepage);
  319.  
  320.     return EXIT_SUCCESS;
  321. }
  322.  
  323.  
  324. 
  325.